/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2013/05/12
* File: SceneNode.cpp
* Blog: http://www.cnblogs.com/zengqh/
**/

#include "enn_scene_node.h"
#include "enn_area_octree.h"

namespace HY
{
SceneNode::SceneNode()
: sg_(0)
, oc_node_(0)
, area_(0)
{
	dirty_flag_.set_flag(DF_WORLD_AABB);
	dirty_flag_.set_flag(DF_OCTREE_POS);
}

SceneNode::~SceneNode()
{
	
}

void SceneNode::addChild( Node* node )
{
	Node::addChild(node);
}

const BoundingBox& SceneNode::getWorldAABB() const
{
	const_cast<SceneNode*>(this)->checkUpdateWorldAABB();
	return world_aabb_;
}

const BoundingBox& SceneNode::getObjectAABB() const
{
	return object_aabb_;
}

void SceneNode::onSelfAdd()
{
	Node::onSelfAdd();
}

void SceneNode::onSelfRemove()
{
	Node::onSelfRemove();
}

void SceneNode::setSelfTransformDirty()
{
	Node::setSelfTransformDirty();

	setWorldAABBDirty();
}

void SceneNode::setParentTransformDirty()
{
	Node::setParentTransformDirty();
	setWorldAABBDirty();
}

void SceneNode::update()
{
	checkUpdateOctreePos();
}

void SceneNode::setWorldAABBDirty()
{
	dirty_flag_.set_flag(DF_WORLD_AABB);
	setOctreePosDirty();
}

void SceneNode::setOctreePosDirty()
{
	dirty_flag_.set_flag(DF_OCTREE_POS);
}

void SceneNode::checkUpdateWorldAABB()
{
	checkUpdateTransform();

	if (dirty_flag_.test_flag(DF_WORLD_AABB))
	{
		world_aabb_ = getObjectAABB();

		world_aabb_.Transform(derived_matrix_);

		dirty_flag_.reset_flag(DF_WORLD_AABB);
	}
}

void SceneNode::checkUpdateOctreePos()
{
	checkUpdateWorldAABB();

	if (dirty_flag_.test_flag(DF_OCTREE_POS))
	{
		if (area_)
		{
			area_->updateSceneNodeInOctree(this);
		}

		dirty_flag_.reset_flag(DF_OCTREE_POS);
	}
}

}